#!groovy

@Library('SovrinHelpers@v2.2.1') _


String name = 'indy-plenum'
String pkgName = name

def plenumTestUbuntu = { offset, increment ->
    try {
        echo 'Ubuntu Test: Checkout csm'
        checkout scm

        echo 'Ubuntu Test: Build docker image'
        def testEnv = dockerHelpers.build(name)

        testEnv.inside('--network host') {
            echo 'Ubuntu Test: Install dependencies'
            testHelpers.install()

            echo 'Ubuntu Test: Test'
            testHelpers.testRunner([resFile: "test-result-plenum-$offset.${NODE_NAME}.txt", testDir: 'plenum', testOnlySlice: "$offset/$increment"])
        }
    }
    finally {
        echo 'Ubuntu Test: Cleanup'
        step([$class: 'WsCleanup'])
    }
}

def plenumTestUbuntuPart1 = {
    plenumTestUbuntu(1, 3)
}

def plenumTestUbuntuPart2 = {
    plenumTestUbuntu(2, 3)
}

def plenumTestUbuntuPart3 = {
    plenumTestUbuntu(3, 3)
}

def ledgerTestUbuntu = {
    try {
        echo 'Ubuntu Test: Checkout csm'
        checkout scm

        echo 'Ubuntu Test: Build docker image'
        def testEnv = dockerHelpers.build(name)

        testEnv.inside {
            echo 'Ubuntu Test: Install dependencies'
            testHelpers.install()

            echo 'Ubuntu Test: Test'
            testHelpers.testJUnit([testDir: 'common', resFile: "test-result-common.${NODE_NAME}.xml"])
            testHelpers.testJUnit([testDir: 'ledger', resFile: "test-result-ledger.${NODE_NAME}.xml"])
            testHelpers.testJUnit([testDir: 'state', resFile: "test-result-state.${NODE_NAME}.xml"])
            testHelpers.testJUnit([testDir: 'storage', resFile: "test-result-storage.${NODE_NAME}.xml"])
        }

    }
    finally {
        echo 'Ubuntu Test: Cleanup'
        step([$class: 'WsCleanup'])
    }
}

def stpTestUbuntu = {
    try {
        echo 'Ubuntu Test: Checkout csm'
        checkout scm

        echo 'Ubuntu Test: Build docker image'
        def testEnv = dockerHelpers.build(name)

        testEnv.inside {
            echo 'Ubuntu Test: Install dependencies'
            testHelpers.install()

            echo 'Ubuntu Test: Test'
            testHelpers.testJUnit([testDir: 'stp_zmq', resFile: "test-result-stp-zmq.${NODE_NAME}.xml"])
        }
    }
    finally {
        echo 'Ubuntu Test: Cleanup'
        step([$class: 'WsCleanup'])
    }
}

def plenumTestWindows = {
    echo 'TODO: Implement me'

    /* win2016 for now (03-23-2017) is not supported by Docker for Windows
     * (Hyper-V version), so we can't use linux containers
     * https://github.com/docker/for-win/issues/448#issuecomment-276328342
     *
     * possible solutions:
     *  - use host-installed OrientDB (trying this one)
     *  - wait until Docker support will be provided for win2016
     */

    //try {
    //    echo 'Windows Test: Checkout csm'
    //    checkout scm

    //    echo 'Windows Test: Build docker image'
    //    dockerHelpers.buildAndRunWindows(name, testHelpers.installDepsWindowsCommands() + ["cd C:\\test && python -m pytest -k orientdb --junit-xml=C:\\testOrig\\$testFile"] /*testHelpers.testJunitWindowsCommands()*/)
    //    junit 'test-result.xml'
    //}
    //finally {
    //    echo 'Windows Test: Cleanup'
    //    step([$class: 'WsCleanup'])
    //}
}

def ledgerTestWindows = {
    try {
        echo 'Windows Test: Checkout csm'
        checkout scm

        echo 'Windows Test: Build docker image'
        dockerHelpers.buildAndRunWindows(name, testHelpers.installDepsWindowsCommands() + testHelpers.testJunitWindowsCommands())
        junit 'test-result.xml'
    }
    finally {
        echo 'Windows Test: Cleanup'
        step([$class: 'WsCleanup'])
    }
}

def stateTestWindows = {
    try {
        echo 'Windows Test: Checkout csm'
        checkout scm

        echo 'Windows Test: Build docker image'
        dockerHelpers.buildAndRunWindows(name, testHelpers.installDepsWindowsCommands() + testHelpers.testJunitWindowsCommands())
        junit 'test-result.xml'
    }
    finally {
        echo 'Windows Test: Cleanup'
        step([$class: 'WsCleanup'])
    }
}

def plenumTestWindowsNoDocker = {
    try {
        echo 'Windows No Docker Test: Checkout csm'
        checkout scm

        testHelpers.createVirtualEnvAndExecute({ python, pip ->
            echo 'Windows No Docker Test: Install dependencies'
            testHelpers.install(python: python, pip: pip, isVEnv: true)
            
            echo 'Windows No Docker Test: Test'
            testHelpers.testRunner(resFile: "test-result.${NODE_NAME}.txt", python: python)
        })
    }
    finally {
        echo 'Windows No Docker Test: Cleanup'
        step([$class: 'WsCleanup'])
    }
}

def ledgerTestWindowsNoDocker = {
    try {
        echo 'Windows No Docker Test: Checkout csm'
        checkout scm   

        testHelpers.createVirtualEnvAndExecute({ python, pip ->
            echo 'Windows No Docker Test: Install dependencies'
            testHelpers.installDepsBat(python, pip)
            
            echo 'Windows No Docker Test: Test'
            testHelpers.testJunitBat(python, pip)
        })
    }
    finally {
        echo 'Windows No Docker Test: Cleanup'
        step([$class: 'WsCleanup'])
    }
}

def stateTestWindowsNoDocker = {
    try {
        echo 'Windows No Docker Test: Checkout csm'
        checkout scm   

        testHelpers.createVirtualEnvAndExecute({ python, pip ->
            echo 'Windows No Docker Test: Install dependencies'
            testHelpers.installDepsBat(python, pip)
            
            echo 'Windows No Docker Test: Test'
            testHelpers.testJunitBat(python, pip)
        })
    }
    finally {
        echo 'Windows No Docker Test: Cleanup'
        step([$class: 'WsCleanup'])
    }
}

def buildDebUbuntu = { releaseVersion, sourcePath, packageVersion=null, missedPkgs=false ->
    def volumeName = "$name-deb-u1604"
    packageVersion = packageVersion ?: releaseVersion

    if (env.BRANCH_NAME != '' && env.BRANCH_NAME != 'master') {
        volumeName = "${volumeName}.${BRANCH_NAME}"
    }
    if (sh(script: "docker volume ls -q | grep -q '^$volumeName\$'", returnStatus: true) == 0) {
        sh "docker volume rm $volumeName"
    }

    // TODO build only missed ones
    dir('build-scripts/ubuntu-1604') {
        sh "./build-$name-docker.sh \"$sourcePath\" $releaseVersion $volumeName $packageVersion"
        if (missedPkgs == [pkgName]) {
            echo "Skip 3rd parties building"
        } else {
            sh "./build-3rd-parties-docker.sh $volumeName"
        }
    }
    return "$volumeName"
}

def options = new TestAndPublishOptions()

options.setApprovers(['QA'])
options.setNotifEmails([
    QA: [
        to: "${env.INDY_NODE_QA_RECIPIENTS ?: ''}",
        cc: "${env.INDY_NODE_RECIPIENTS ?: ''}"
    ],
    success: [
        to: "${env.INDY_NODE_RECIPIENTS ?: ''}"
    ],
    fail: [
        to: "${env.INDY_NODE_RECIPIENTS ?: ''}"
    ]
])
options.setPkgName(pkgName)

// TODO duplicates list from build scripts
options.setBuiltPkgs([
    'rocksdb': '5.8.8',
    'python3-ioflo': '1.5.4',
    'python3-orderedset': '2.0',
    'python3-base58': '1.0.0',
    'python3-prompt-toolkit': '0.57',
    'python3-rlp': '0.5.1',
    'python3-sha3': '0.2.1',
    'python3-libnacl': '1.6.1',
    'python3-six': '1.11.0',
    'python3-portalocker': '0.5.7',
    'python3-sortedcontainers': '1.5.7',
    'python3-setuptools': '38.5.2',
    'python3-dateutil': '2.6.1',
    'python3-semver': '2.7.9',
    'python3-pygments': '2.2.0',
    'python3-psutil': '5.4.3',
    'python3-pyzmq': '18.1.0',
    'python3-intervaltree': '2.1.0',
    'python3-jsonpickle': '0.9.6',
    'python3-rocksdb': '0.6.9',
    'python3-pympler': '0.5',
    'python3-packaging': '19.0'
])


options.setPrContexts([env.INDY_GITHUB_PR_REQUIRED_CONTEXT ?: "ci/hyperledger-jenkins/pr-merge"])
testAndPublish(
    name,
    [
        ubuntu: [plenum1: plenumTestUbuntuPart1,
        plenum2: plenumTestUbuntuPart2,
        plenum3: plenumTestUbuntuPart3,
        ledger: ledgerTestUbuntu,
        stp: stpTestUbuntu]
    ],
    true, options, [ubuntu: buildDebUbuntu], 'plenum'
)
